<?php
/**
 * @link https://ym2.cleverstone.top
 * @copyright Copyright (c) 2020 Yii Manager Software LLC
 */

namespace backend\controllers;

use builder\base\BaseController;
use builder\helper\H5;
use builder\table\TableBuilder;
use common\models\Admin;
use common\models\AppLogs;
use common\models\Tlog;

/**
 * 应用和操作日志
 * @author cleverstone
 * @since ym2.0
 */
class LogController extends BaseController
{
    public $actionVerbs = [
        'app' => ['GET'],
        'delete' => ['POST'],
        'app-message' => ['GET'],

        'operation' => ['GET'],
        'odelete' => ['POST'],
    ];

    /**
     * 应用日志列表
     * @return string
     * @throws \yii\base\InvalidConfigException
     */
    public function actionApp()
    {
        $table = TableBuilder::instance(['id' => 'log_app']);

        if ($this->isAjax) {
            $table->setQuery(function () {
                $params = $this->filteredGet;
                $startAt = null;
                $endAt = null;
                if (!empty($params['create_at'])) {
                    list($startAt, $endAt) = array_map('trim', explode('/', $params['create_at']));
                }

                $query = AppLogs::query();
                $query->andFilterWhere([
                    'and',
                    [
                        'or',
                        ['like', 'category', isset($params['keyword']) ? $params['keyword'] : null],
                        ['like', 'prefix', isset($params['keyword']) ? $params['keyword'] : null],
                        ['like', 'message', isset($params['keyword']) ? $params['keyword'] : null],
                    ],
                    ['level' => isset($params['level']) ? $params['level'] : null],
                    ['between', 'created_at', $startAt, $endAt],
                ]);

                return $query;
            })
                ->setOrderBy(['id' => SORT_DESC])
                ->setColumns([
                    'id',
                    'level' => function ($row) {
                        $level = $row['level'];
                        return H5::badge(
                            AppLogs::levelLabel($level),
                            AppLogs::levelLabelColor($level)
                        );
                    },
                    'category',
                    'prefix',
                    'created_at',
                ]);
        } else {
            $table->setTitle('应用日志')
                ->setLimit(20)
                ->setTableHead([
                    $this->tableHead->field('id')->title('ID'),
                    $this->tableHead->field('level')->title('错误等级'),
                    $this->tableHead->field('category')->title('操作类型'),
                    $this->tableHead->field('prefix')->title('客户端'),
                    $this->tableHead->field('created_at')->title('记录时间'),
                    $this->tableHead->toolbar()->title('操作项')->width(120),
                ])
                ->setRowOperation([
                    $this->rowOperation->modal()->title('查看日志内容')->route('log/app-message')->closeBtn(),
                ])
                ->setToolbarCustom([
                    $this->toolbarCustom->ajax()->title('删除五个月以前')->route('log/delete')->btnClass('layui-btn-danger')->method(),
                ])
                ->setToolbarFilter([
                    'keyword' => $this->toolbarFilter->text()->label('关键词')->placeholder('请输入')->uiClass('w-330'),
                    'level' => $this->toolbarFilter->select()
                        ->label('等级')
                        ->placeholder('请选择')
                        ->options([
                            'DEBUG' => 'DEBUG',
                            'INFO' => 'INFO',
                            'WARNING' => 'WARNING',
                            'ERROR' => 'ERROR',
                        ])
                        ->uiConfig('minimumResultsForSearch', -1)
                        ->uiClass('w-330 mx-md-3'),
                    'create_at' => $this->toolbarFilter->datetime()->label('记录时间')->placeholder('请选择')->uiClass('w-330 mr-md-3'),
                ]);
        }

        return $table->render();
    }

    /**
     * 删除五个月前的应用日志
     * @return string
     */
    public function actionDelete()
    {
        $lastFive = date('Y-m-d H:i:s', strtotime('-5 months'));
        $result = AppLogs::deleteAll(['<=', 'created_at', $lastFive]);

        if ($result) {
            return $this->asOk('删除五月以前的【应用日志】成功, 删除数量:' . $result . '条');
        }

        return $this->asOk('五月以前【应用日志】为空, 不需要删除');
    }

    /**
     * 信息
     * @param int $id 日志ID
     * @return string
     * @throws \Throwable
     */
    public function actionAppMessage($id)
    {
        $detail = AppLogs::query(['message'])->where(['id' => $id])->one();
        if (empty($detail)) {
            return $this->renderContentX(H5::alert('空', 'info'));
        }

        return $this->renderContentX(H5::tag('pre', $detail['message'], ['class' => 'layui-code m-3']));
    }

    /**
     * 操作日志列表
     * @return string
     * @throws \Throwable
     */
    public function actionOperation()
    {
        $userColumns = Admin::query(['username'])->indexBy('id')->column();
        $userColumns[0] = '⭐system';
        ksort($userColumns);

        $table = TableBuilder::instance(['id' => 'log_operation']);

        if ($this->isAjax) {
            $table->setColumnDependency($userColumns)
                ->setQuery(function () {
                    $params = $this->filteredGet;
                    $startAt = null;
                    $endAt = null;
                    if (!empty($params['create_at'])) {
                        list($startAt, $endAt) = array_map('trim', explode('/', $params['create_at']));
                    }

                    $query = Tlog::query();
                    $query->andFilterWhere([
                        'and',
                        [
                            'or',
                            ['like', 'route', isset($params['keyword']) ? $params['keyword'] : null],
                            ['like', 'category', isset($params['keyword']) ? $params['keyword'] : null],
                            ['like', 'prefix', isset($params['keyword']) ? $params['keyword'] : null],
                            ['like', 'message', isset($params['keyword']) ? $params['keyword'] : null],
                        ],
                        ['aid' => isset($params['aid']) ? $params['aid'] : null],
                        ['between', 'created_at', $startAt, $endAt],
                    ]);

                    return $query;
                })
                ->setOrderBy(['id' => SORT_DESC])
                ->setColumns([
                    'x_name' => function ($row, $dependency) {
                        return !empty($dependency[$row['aid']]) ? $dependency[$row['aid']] : '-';
                    },
                    'route',
                    'category',
                    'message',
                    'prefix',
                    'created_at',
                ]);
        } else {
            $table->setTitle('操作日志列表')
                ->setLimit(20)
                ->setTableHead([
                    $this->tableHead->field('x_name')->title('用户')->width(120),
                    $this->tableHead->field('route')->title('访问路由')->width(200),
                    $this->tableHead->field('category')->title('操作类型')->width(200),
                    $this->tableHead->field('message')->title('日志内容')->minWidth(300),
                    $this->tableHead->field('prefix')->title('客户端')->width(200),
                    $this->tableHead->field('created_at')->title('记录时间')->width(150),
                ])
                ->setToolbarCustom([
                    $this->toolbarCustom->ajax()->title('删除五个月以前')->route('log/odelete')->btnClass('layui-btn-danger')->method(),
                ])
                ->setToolbarFilter([
                    'keyword' => $this->toolbarFilter->text()->label('关键词')->placeholder('请输入')->uiClass('w-330'),
                    'aid' => $this->toolbarFilter->select()
                        ->label('用户')
                        ->placeholder('请选择')
                        ->options($userColumns)
                        ->uiClass('w-330 mx-md-3'),
                    'create_at' => $this->toolbarFilter->datetime()->label('操作时间')->placeholder('请选择')->uiClass('w-330 mr-md-3'),
                ]);
        }

        return $table->render();
    }

    /**
     * 删除五月以前的操作日志
     * @return string
     */
    public function actionOdelete()
    {
        $lastFive = date('Y-m-d H:i:s', strtotime('-5 months'));
        $result = Tlog::deleteAll(['<=', 'created_at', $lastFive]);
        if ($result) {
            return $this->asOk('删除五月以前的【操作日志】成功, 删除数量:' . $result . '条');
        }

        return $this->asOk('五月以前【操作日志】为空, 不需要删除');
    }
}